package cn.com.cis.service;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.concurrent.Executors;

import org.springframework.stereotype.Service;

import cn.com.cis.utils.FileUtils;
import cn.com.cis.utils.jobExecute.CisJobProgressIndicator;
import scriptella.configuration.ConfigurationEl;
import scriptella.configuration.ConfigurationFactory;
import scriptella.execution.EtlExecutor;
import scriptella.execution.EtlExecutorException;

/**
 * Created by hg on 15-8-13.
 */
@Service
public class ETLExecutorService implements Serializable {
	
	private static ArrayList<java.util.concurrent.ExecutorService> executorServices = new ArrayList<java.util.concurrent.ExecutorService>();

	private static final long serialVersionUID = -6192122525989434829L;

	public void execute(final CisJobProgressIndicator cisIndicator, File xmlFile) throws MalformedURLException, InterruptedException {
		ConfigurationFactory factory = new ConfigurationFactory();
		factory.setResourceURL(xmlFile.toURI().toURL());
		ConfigurationEl etlConfig = factory.createConfiguration();

		final EtlExecutor etlExecutor = new EtlExecutor();
		etlExecutor.setConfiguration(etlConfig);

		// 执行xml作业时会另起线程，此线程写入一条作业执行进度的log
		// 这个新起的线程与插入的那条log是关联的
		// 因此在log中记录这个线程的内存地址，以便在某些特殊的情况下查找并手动结束这个线程
		java.util.concurrent.ExecutorService service = Executors.newSingleThreadExecutor();
		cisIndicator.setExecutorThread(service.toString());
		
		service.submit(new Runnable() {

			@Override
			public void run() {
				try {
					etlExecutor.execute(cisIndicator);
				} catch (EtlExecutorException e) {
					e.printStackTrace();
					
					if (cisIndicator != null) {
						StringWriter fullErrorMessage = new StringWriter();
						e.printStackTrace(new PrintWriter(fullErrorMessage));
						
						// 输出错误堆栈到log表中
						cisIndicator.onError(fullErrorMessage.toString());
					}
				}
			}
		});
		
		service.shutdown();
		executorServices.add(service);
	}

	public void execute(CisJobProgressIndicator cisIndicator, String filePath) throws MalformedURLException, InterruptedException {
		File xmlFile = new File(filePath);

		execute(cisIndicator, xmlFile);
	}

	public void execute(String xml, CisJobProgressIndicator cisIndicator) throws EtlExecutorException, IOException, InterruptedException {
		File tmpFile = File.createTempFile("etlJob", "xml");
		boolean writeSuccess = FileUtils.writesString2File(xml, tmpFile);

		if (!writeSuccess) {
			throw new IOException("write xml string to temp file failed.");
		}

		execute(cisIndicator, tmpFile);

		tmpFile.delete();
	}

	public static ArrayList<java.util.concurrent.ExecutorService> getExecutorServices() {
		return executorServices;
	}

}
